// Vue 
// MVVM框架
//变成方式：MVVM：数据驱动视图。
//核心：Vue实力管理模板内容

// 数据驱动视图
//把需要改变视图的数据都初始化到VUE中,
//然后我们就可以通过修改Vue中的数据，从而实现对视图的更新。
//当前JS脚本依赖全局中的vue
;(function(Vue){
	const todos = [
		{
			id:1,
			title:'吃饭',
			completed:false
		},
		{
			id:2,
			title:'睡觉',
			completed:true
		},
		{
			id:3,
			title:'打豆豆',
			completed:true
		}
	]


	//什么时候需要封装自定义指令，当你需要进行一些底层DOM操作的时候，使用自定义指令更为方便。

	// 注册一个全局自定义指令 `v-focus`

	//第一个参数：指令名称，focus
	//使用的时候，必须加上v-前缀来使用
	//后面会解释为什么一个简简单单的自动获得焦点都需要封装一个自定义指令，
	//Vue带来便利的同事也会有一些让人头疼的问题，所以在软件开发中，有这么一句话:没有银弹。
	Vue.directive('focus', {
	// 当被绑定的元素插入到 DOM 中时……
		inserted: function (el) {
			// 聚焦元素
			// el.focus()
			//el就是作用了v-focus的DOM元素
			console.log(el)
			el.focus()
		}
	})

	//点击的时候自动激活样式
	Vue.directive('auto-active', {
	// 当被绑定的元素插入到 DOM 中时……
	//这里就是村原生DOM操作
		inserted: function (el) {
			// 聚焦元素
			// el.focus()
			//el就是作用了v-focus的DOM元素
			console.log(el)
			//ul a 
			//给 a注册点击事件
			var links = el.getElementsByTagName('a')  //伪数组

			// ES转为数组
			Array.from(links).forEach(function(link){
				console.log(link)
				link.onclick = function(){
					console.log(link)
				}
			})
			console.log(links)
		}
	})


	window.app = new Vue({
		el:'#todoapp',
		data:{
			// todos:todos
			// 同名时候可以简写
			todos,
			//这里不要使用this因为this指向的是window
			//所以这里无法实现你想要的结果
			// leftCount:this.todos.filter(item => !item.completed).length
			// leftCount:(function(){
			// 	console.log(123)
			// 	return 1342
			// })()		
			filterStat:'all',
			currentEditing:null,
			//全选按钮的状态
			toggleAllStat:true
		},
		methods:{
			// addTodo:function(event){
			// 	console.log(event)
			// }
			// ES6对象属性函数的简写方式等价于上面 ，
			// 没有任何特殊的特性，仅仅是简写而已
			addTodo(event){
				// console.log('addTodo')
				// 1.获取文本框中用户输入的数据
				// 2.判断数据是否非空
				// 3.添加到数组中
				// 4.清空文本框
				// console.log(this.todoText)
				console.log(event.target.value)				
				var todoText = event.target.value.trim()
				if(!todoText.length){
					return 
				}

				var id = this.todos[this.todos.length-1].id + 1
				//当数组发生变化，则绑定渲染该数组的
				this.todos.push({
					id,
					title:todoText,
					completed:false
				})
				event.target.value= ''
			},
			//全选反选
			toggleAll(event){
				//获取点击的checkbox的选中状态
				var checked = event.target.checked
				this.todos.forEach((todo)=> todo.completed = checked)
				// this.todos[0].completed = true
			},

			//删除任务项
			removeTode(delIndex,event){
				console.log(delIndex,event)
				this.todos.splice(delIndex,1)
			},
			//删除所有已完成任务项目
			//找到所有已完成的任务项，把其删除
			removeAllDone(){
				//方法一：
				//把所有需要保留的数据过滤出来，然后重新赋值给todos
				// this.todos = this.todos.filter((item,index) => {
				// 	return !item.completed
				// })
				//方法二：
				//如果想要就在遍历的过程去删除，则可以使用for循环
				//每删除一个，我们可以控制让索引 -- 
				for (let i= 0 ; i < this.todos.length; i++){
					if(this.todos[i].completed){
						this.todos.splice(i,1);
						i--;
					}
				}
			},

			//方法也可以用于魔板绑定
			//在魔板中调用方法，方法的返回值将会渲染到绑定的位置
			// getLeftCount(){
			// 	console.log(123);
			// return this.todos.filter(item => !item.completed).length
			// // return 123
			// }


			//双击label获得editing编辑样式
			getEditing(){
				console.log('editing')
				
			},
			//保存编辑项
			saveEdit(item,index,event){
				//1.拿到文本框中的数据
				//  非空校验
				//  如果为空，则直接删除这个item
				//  如果不为空，则修改任务项的title数据
				var editText = event.target.value.trim()
				// if(!editText.length){
					//将数据直接从数组中移除
					// return this.todos.splice(index,1)
				// }
					//2.将数据设置到任务项中
				// item.title = editText
				//优化简写
				!editText.length?
				this.todos.splice(index,1):
				item.title = editText
				//3.去除editing样式
				this.currentEditing = null
				console.log(event.target.value)
			},

			//状态切换,
			toggle(item,event){
				console.log(event.target.checked,item.completed)

				//之前这里没有这个问题，应该Vue更新了新的机制了。
				// 声明周期、模板更新的问题
				// 这里的解决方案就是把你的代码放到Vue.nextTick()的回调函数里。
				Vue.nextTick(() => {
					this.toggleAllStat = this.todos.every(item =>item.completed)
				})
				//every
				//some 
				//	只要有一个未选中，则让全选按钮不选中.
				//	否则，则让全选按钮选中。
				//全选按钮的状态
				// this.toggleAllStat = this.todos.every(item => item.completed)
			}

		},
		// 改属性比较特殊，从代码看是一个方法，但是只能当做一个属性来使用。
		//也就是说，在模板中不能调用它，只能当做属性来使用它
		//定义计算属性，会依赖于内部data的数据
		//原理：Objecy.defineProperty API高级属性定义方式 get访问，set设置
		computed:{
			leftCount:function(){
				return this.todos.filter(item => !item.completed).length
			},
			filterTodos:function(){
				switch(this.filterStat){
					case 'active':
						return this.todos.filter(item => !item.completed)
						break
					case 'completed':
						return this.todos.filter(item => item.completed)
						break
					default:
						return this.todos
						break
				}
				// all返回所有的todos
				// active返回所有completed为false的任务
				// completed返回所有completed为true的任务
			},
			//使用计算属性的方式处理全选的联动效果
			toggoleComputed:function(){
				return this.todos.every(item => item.completed)
			}
		},
	})

	window.onhashchange = function(){
		//得到点击的路由hash
		console.log(window.location.hash)
		var hash = window.location.hash.substr(2) || 'all'

		//设置到程序中的过滤状态
		//过滤状态一旦改变，则计算属性会感知到这个filterStat变了
		//当filterTodos重新计算执行之后，数据得到了更新，则自动同步更新到视图中。
		window.app.filterStat = hash
	}
	//页面第一次进来，执行一次。否则无法保持状态  hash只有状态改变的时候才会执行
	window.onhashchange()



})(Vue)